/* eslint-disable unicorn/prevent-abbreviations */
import {
  Module,
  Mutation,
  VuexModule,
  getModule,
  Action,
} from 'vuex-module-decorators'
import store from '@/store'
import { queryDatalist, importData } from '@/api/data-list'
import { Compare } from '@/util/data-view-table-helper'
import { allNodeList, taskComplexLoad, taskQueryById } from '@/api/task'
import {
  apiGetHistoryList,
  apiAddHistory,
  apiDelHistory,
  apiUpdateHistory,
} from '@/api/data-clean'
import { message } from 'ant-design-vue'
import { cloneDeep, isEqual, isFunction } from 'lodash'
import { ComputeSpaceAfterNode } from '@/components/studio/data/util-pipeline'
import SelectionType from '@/util/selection-type'
import VROptionSetModeInteface from '@/util/vr-option-set-mode-interface'
import SelectionInfo from '@/util/selection-info-interface'

// project 数据
export interface Data {
  type: string
  id: number
  name: string
}
export interface IKeyValueStore {
  [key: string]: any
}

export interface IColumn {
  name: string
  type: number
  desc?: string
  semantic?: string
}

export interface NodeStatus {
  status: string
  logInfo: string
}

export interface NodeStatusMap {
  [id: string]: NodeStatus
}

/**
 * 单元格信息
 */
export interface CellInfo {
  rowIndex: number
  columnName: string
  _record_id_: string
  cellValue: string
}

export interface TableVueInstance {
  clearAllSelect(): void
  clearTableSlection: void
  checkHeight(): void
}

export { default as OptionPreViewAction } from '@/util/data-selection-actions'
export { default as SelectionInfo } from '@/util/selection-info-interface'

@Module({ dynamic: true, namespaced: true, name: 'GraphViewStore', store })
class GraphViewStore extends VuexModule {
  private _selectNode: any = {} // 选择的node
  private visualWindowShow: boolean = false // 新建/编辑可视化窗口是否显示
  private datasetName: string = ''
  private pipelineId: number | null = null
  private currentData: any = []
  private favoriteStatus: boolean = true // 收藏开关，每次收藏将值取非，对应组件监听该变量改变来重新拉取可视化信息
  private oldItems: any = null // 已有配置项（可视化重编辑）
  private _historyList: IKeyValueStore[] = [] // 操作历史列表
  private _currentHistory: IKeyValueStore | null = null
  private _currentCategoryData: any = null // 当前选中模型节点的模型数据
  private _graphAnalysisData: any = { categories: [], nodes: [], links: [] } // 图分析数据
  private _dragBarMode: any = 0
  private _taskId: any
  private _graphSourceTables: any = [] // 图构建关联的源数据
  private _tableColumns: IColumn[] = [] // 表列字段
  private _tableData: IKeyValueStore[] = [] // 表明细数据
  private _tableHeight: number = 128 // 底部表格高度
  private _isEditHistory: boolean = false // 是否编辑操作历史
  private _executionCompletionTime: number = 0 // 链路执行完成
  private _nodeStatusMap: NodeStatusMap = {} // 节点状态
  private _isSideMenuShow: boolean = true // 选择数据视图和可视化视图的菜单是否显示
  private _isSidePanelShow: boolean = true // 数据源和算子的面板是否显示

  private _columnFilters: any[] = [] // 列字段上的筛选条件
  private _selectedColumns: IColumn[] = [] // node-edit-panel中选中的字段卡片
  private _mergeColumnHotKey: boolean = false
  private _savingWidgetConfig: any = null // 正在保存的推荐可视化
  private _graphSize: any = {}

  // table列表交互缓存相关数据
  private _tb_selectColumns: IColumn[] = [] // 选中列
  private _tb_selectRowNumbers: number[] = [] // 选中行号
  private _tb_selectRowDatas: any[] = [] // 选中行的数据
  private _tb_selectCellDatas: Array<CellInfo> = [] // 选中的单元格
  private _tb_selectionType: SelectionType = SelectionType.none // 当前表格选择模式
  private _tb_vue_instance: TableVueInstance | null = null
  private _tb_selectionInfo: SelectionInfo | null = null

  // 隐藏预览面板的计时器
  private _vr_timer: any = null
  // 推荐右侧预览窗口y定位
  public hoverYPos: number = -1

  // 需要替换的值
  public columnFilterSelectNullCellsResetValue: string = ''
  // 链接符号
  public columnMergeColumnsJoinString: string = '-'
  // 新字段名称
  public columnMergeColumnsNewColumnName: string = ''

  // 单元格重新赋值所填入的值
  public cellResetSelectCellResetValue: string = ''

  // 刷选需要替换的关键字
  public selectionReplaceKeyword: string = ''
  // 刷选需要替换为该值
  public selectionReplaceValue: string = ''

  // 当选中一列时当前列是否含有空值
  public columnHasNullCell: boolean = true
  // 行操作状态下，是否存在缺失值的行
  public tableHasNullRows: boolean = true
  // 匹配的值
  public tableValueContains: Array<string> | null = null

  // 推荐指令组点击确定后相关指令信息
  public vrCurrenSetMode: VROptionSetModeInteface | null = null

  public tableDataCount: number = 0

  public _projectId = 0

  // table|推荐相关操作--------------------------------------start
  @Mutation
  setTableValueContains(containsValue: Array<string> | null) {
    this.tableValueContains = containsValue
  }

  /**
   * 清空状态以及推荐填入信息
   */
  @Mutation
  public resetVrSettingValues() {
    this.columnFilterSelectNullCellsResetValue = ''
    this.columnMergeColumnsJoinString = '-'
    this.columnMergeColumnsNewColumnName = ''
    this.cellResetSelectCellResetValue = ''
    this.selectionReplaceKeyword = ''
    this.selectionReplaceValue = ''
    // 相关填入信息
    this.tableValueContains = null
  }

  @Mutation
  public setTableDataCount(count: number) {
    this.tableDataCount = count
  }

  @Mutation
  public setTableHasNullRows(hasNull: boolean) {
    this.tableHasNullRows = hasNull
  }

  @Mutation
  public setColumnHasNullCell(hasNull: boolean) {
    this.columnHasNullCell = hasNull
  }

  @Mutation
  public setProjectId(data: any) {
    this._projectId = data
  }

  @Mutation
  public setselectionReplaceKeyword(value: string = '') {
    this.selectionReplaceKeyword = value
  }

  @Mutation
  public setSelectionReplaceValue(value: string = '') {
    this.selectionReplaceValue = value
  }

  @Mutation
  public setCellResetSelectCellResetValue(value: string) {
    this.cellResetSelectCellResetValue = value
  }

  @Mutation
  public setColumnMergeColumnsJoinString(joinString: string) {
    this.columnMergeColumnsJoinString = joinString
  }

  @Mutation
  public setColumnMergeColumnsNewColumnName(columnName: string) {
    this.columnMergeColumnsNewColumnName = columnName
  }

  @Mutation
  public setColumnFilterSelectNullCellsResetValue(value: string) {
    this.columnFilterSelectNullCellsResetValue = value
  }

  @Mutation
  public clearTableSelection() {
    if (this._tb_vue_instance) {
      this._tb_vue_instance.clearAllSelect()
    }
    this._tb_selectColumns = []
    this._tb_selectRowNumbers = []
    this._tb_selectRowDatas = []
    this._tb_selectCellDatas = []
    this._tb_selectionType = SelectionType.none
  }

  @Mutation
  public setTableSelectionInfo(selectionInfo: SelectionInfo | null) {
    this._tb_selectionInfo = selectionInfo
  }

  @Mutation
  public setDataTableInstance(instance: TableVueInstance) {
    if (instance && isFunction(instance.clearTableSlection)) {
      this._tb_vue_instance = instance
    }
  }

  @Mutation
  public setTableSelectColumns(columns: IColumn[]) {
    this._tb_selectColumns = columns
  }

  @Mutation
  public toggleTableSelectColumn(column: IColumn) {
    const index = this._tb_selectColumns.findIndex(
      (columnItem) => columnItem.name === column.name
    )
    if (index > -1) {
      this._tb_selectColumns.splice(index, 1)
    } else {
      this._tb_selectColumns = [...this._tb_selectColumns, column]
    }
  }

  @Mutation
  public setTableSelectRowDatas(data: any[]) {
    this._tb_selectRowDatas = data
  }

  @Mutation
  public setTableSelectRowNumbers(rows: number[]) {
    this._tb_selectRowNumbers = rows
  }

  @Mutation
  public toggleTableSelectRowNumber(rowIndex: number) {
    if (this._tb_selectRowNumbers.includes(rowIndex)) {
      this._tb_selectRowNumbers.splice(rowIndex, 1)
    } else {
      this._tb_selectRowNumbers.push(rowIndex)
    }
  }
  @Mutation
  public toggleTableSelectData(data: any) {
    let tag = false
    let dataindex = -1
    this._tb_selectRowDatas.forEach((dataItem, index) => {
      if (Compare(dataItem, data)) {
        tag = true
        dataindex = index
      }
    })
    if (tag) {
      this._tb_selectRowDatas.splice(dataindex, 1)
    } else {
      this._tb_selectRowDatas.push(data)
    }
  }

  @Mutation
  public setTableSelectCells(cells: Array<CellInfo>) {
    this._tb_selectCellDatas = cells
  }

  @Mutation
  public toggleTableSelectCell(cell: CellInfo) {
    // 判断新的cell是否在同一列
    const isSameColumn = this._tb_selectCellDatas.every((item) => {
      return item.columnName === cell.columnName
    })
    if (!isSameColumn) {
      this._tb_selectCellDatas = [cell]
    } else {
      const index = this._tb_selectCellDatas.findIndex((cellItem) => {
        return (
          cellItem.rowIndex === cell.rowIndex &&
          cellItem.columnName === cell.columnName
        )
      })
      if (index > -1) {
        this._tb_selectCellDatas.splice(index, 1)
      } else {
        this._tb_selectCellDatas.push(cell)
      }
    }
  }

  /**
   * 立即清除预览弹框
   */
  @Mutation
  public clearDataPreviewImmediately() {
    clearTimeout(this._vr_timer)
    this.hoverYPos = -1
  }

  @Mutation
  public setTableSelectiontype(selectionType: SelectionType) {
    this._tb_selectionType = selectionType
  }

  @Mutation
  public setTableVrCurrenSetMode(optionInfo: VROptionSetModeInteface | null) {
    this.vrCurrenSetMode = optionInfo
  }
  /**
   * DataTable实例,用于外部调用
   */
  public get dataTableInstance() {
    return this._tb_vue_instance
  }

  public get tableSelectCells() {
    return this._tb_selectCellDatas
  }

  public get projectId() {
    return this._projectId
  }

  public get tableSelectColumns() {
    return this._tb_selectColumns
  }

  public get tableSelectRowNumbers() {
    return this._tb_selectRowNumbers
  }

  public get tableSelectRowDatas() {
    return this._tb_selectRowDatas
  }

  public get tableSelectionType() {
    return this._tb_selectionType
  }

  /**
   * 获取数据表刷选信息
   */
  public get tableSelectionInfo() {
    return this._tb_selectionInfo
  }

  /**
   * 获取数据表刷选文本
   */
  public get tableSelctionText() {
    return this._tb_selectionInfo ? this._tb_selectionInfo.selection : ''
  }

  // 可视化对比状态
  private _comparisonStatus: boolean = false

  @Mutation
  public setComparisonStatus(status: boolean) {
    this._comparisonStatus = status
  }

  public get comparisonStatus() {
    return this._comparisonStatus
  }

  // 可视化对比的节点 Ids
  private _comparisonNodes: any[] = []
  public get comparisonNodes() {
    return this._comparisonNodes
  }

  public get comparisonNodeIds() {
    return this._comparisonNodes.map((node: any) => node.id)
  }
  @Mutation
  public setComparisonNodes(nodes: any[]) {
    this._comparisonNodes = nodes
  }

  // pipeline 中选择的节点对比状态
  @Action({ commit: 'setComparisonNodes' })
  public async changeComparisonNodes(node: any) {
    const nodes = cloneDeep(this._comparisonNodes)
    const nodeIds = nodes.map((item: any) => item.id)
    if (nodeIds.includes(node.id)) {
      nodes.splice(nodeIds.indexOf(node.id), 1)
    } else {
      nodes.push(node)
    }
    return nodes
  }

  public get getOldItems() {
    return this.oldItems
  }

  public get getFavoriteStatus() {
    return this.favoriteStatus
  }

  public get getCurrentData() {
    return this.currentData
  }

  public get getDatasetName() {
    return this.datasetName
  }

  public get getVisualWindowShow() {
    return this.visualWindowShow
  }

  public get getPipelineId() {
    return this.pipelineId
  }

  @Mutation
  public setOldItems(items: any) {
    this.oldItems = items
  }

  @Mutation
  public setFavoriteStatus(favoriteStatus: boolean) {
    this.favoriteStatus = favoriteStatus
  }

  @Mutation
  public setCurrentData(currentData: any) {
    this.currentData = currentData
  }

  @Mutation
  public setPipelineId(pipelineId: number | null) {
    this.pipelineId = pipelineId
  }

  @Mutation
  public setDatasetName(name: string) {
    this.datasetName = name
  }

  @Mutation
  public setVisualWindowShow(status: boolean) {
    this.visualWindowShow = status
  }

  @Mutation
  public setCurrentHistory(history: IKeyValueStore | null) {
    this._currentHistory = history
  }

  @Mutation
  public setIsEditHistory(flag: boolean) {
    this._isEditHistory = flag
  }

  public get selectNode() {
    return this._selectNode
  }

  public get historyList() {
    return this._historyList
  }

  public get currentHistory() {
    return this._currentHistory
  }

  public get currentCategoryData() {
    return this._currentCategoryData
  }

  public get graphAnalysisData() {
    return this._graphAnalysisData
  }

  public get dragBarMode() {
    return this._dragBarMode
  }

  public get taskId() {
    return this._taskId
  }

  public get graphSourceTables() {
    return this._graphSourceTables
  }

  public get tableColumns() {
    return this._tableColumns
  }

  public get tableData() {
    return this._tableData
  }

  public get tableHeight() {
    return this._tableHeight
  }

  public get isEditHistory() {
    return this._isEditHistory
  }

  // pipeline 中选择的节点
  @Action({ commit: 'setSelectNode' })
  public async changeSelectNode(node: any) {
    return node
  }

  // 数据源--query data list
  @Action({ commit: 'setProjectData' })
  public async loadProjectData(projectId: number) {
    const postData = {
      projectId,
    }
    const response = await queryDatalist({ data: postData })
    return response.data.result
  }

  // 数据源--加载数据
  @Action({ commit: 'setProjectData' })
  public async importData(parameters: any) {
    const postData = {
      datasetIds: parameters.checkDataIds,
      projectId: parameters.projectId,
    }
    const result = await importData({ data: postData })
    if (result.data.code === 100) {
      message.success(result.data.message)
    } else {
      message.error(result.data.message)
    }
    const response = await queryDatalist({
      data: { projectId: postData.projectId },
    })
    return response.data.result
  }

  // 选择的node
  @Mutation
  public setSelectNode(node: any) {
    this._selectNode = node
  }

  @Mutation
  private setHistoryList(data: any) {
    this._historyList = data.historyList
    this._currentHistory = data.currentHistory || data.historyList.slice(-1)[0]
  }

  @Mutation
  public setDragBarMode(data: any) {
    this._dragBarMode = data
  }

  @Mutation
  public setTaskId(data: any) {
    this._taskId = data
  }

  @Mutation
  public setGraphSourceTables(data: any) {
    this._graphSourceTables = data
  }

  @Mutation
  public setCurrentCategoryData(data: any) {
    this._currentCategoryData = data
  }

  @Mutation
  public setGraphAnalysisData(data: any) {
    this._graphAnalysisData = data
  }

  @Mutation
  public setTableData(data: any) {
    if (data.mode !== 'detail') {
      // detail: 只是table detail 发生变化(适用于表格滚动加载或者head不变的情况下进行数据筛选), all: header和detail都变化
      const stamp = +new Date()
      data.head.forEach((item: IKeyValueStore) => {
        item._stamp = stamp
      })
    }
    this._tableColumns = data.head
    this._tableData = data.data
  }

  @Mutation
  public setTableHeight(height: number) {
    this._tableHeight = height
  }

  @Action({ commit: 'setHistoryList' })
  public async getHistoryList(params?: any) {
    const response = await apiGetHistoryList({
      data: {
        taskId: this._selectNode.id,
        ...params,
      },
    })
    const data = response.data.result
    const errorIndex = data.findIndex(
      (item: any) => item.data.status !== 'SUCCESS'
    )

    return {
      historyList: data,
      currentHistory: errorIndex > -1 ? data[errorIndex - 1] : null,
    }
  }

  /**
   * 添加操作历史记录
   */
  @Action
  public async addHistory(params?: any) {
    const response = await apiAddHistory({
      data: {
        projectId: this._selectNode.projectId,
        taskId: this._selectNode.id,
        taskName: this._selectNode.name,
        ...params,
      },
    })
    return response.data
  }

  /**
   * 更新操作历史记录
   */
  @Action
  public async updateHistory(params?: any) {
    const response = await apiUpdateHistory({
      data: {
        projectId: this._selectNode.projectId,
        taskId: this._selectNode.id,
        taskName: this._selectNode.name,
        ...params,
      },
    })
    return response.data
  }

  /**
   * 删除操作历史记录
   * @param params id: xxx 要删除的历史记录id
   */
  @Action
  public async delHistory(params: any) {
    const response = await apiDelHistory({
      data: {
        projectId: this._selectNode.projectId,
        taskId: this._selectNode.id,
        ...params,
      },
    })
    return response.data
  }

  public get columnFilters() {
    return this._columnFilters
  }

  @Mutation
  public setColumnFilters(columnFilters: any[]) {
    if (!isEqual(this._columnFilters, columnFilters)) {
      this._columnFilters = columnFilters
    }
  }

  // 2020/11/11
  private _pipelineNodes: any[] = [] // pipeline 所有节点
  public get pipelineNodes() {
    return this._pipelineNodes
  }
  // pipeline 所有节点
  @Mutation
  private setPipelineNodes(nodes: Array<any>) {
    this._pipelineNodes = nodes
  }
  //  所有节点
  @Action({ commit: 'setPipelineNodes' })
  public async queryPipelineNodes(parameters: any) {
    let nodeList: any = null
    const response = await allNodeList({ data: parameters })
    if (response.data.code === 100) {
      nodeList = response.data.result
      // if(this._selectNode) {
      //   this.setSelectNode(nodeList.filter((node: any) => node.id === this._selectNode.id)[0])
      // }
    }
    return nodeList
  }

  // 清空 pipeline nodes
  @Action({ commit: 'setPipelineNodes' })
  public async initPipelineNodes() {
    return []
  }

  // 节点确认编辑节点配置时间戳
  private _confirmEditTime: number = 0
  public get confirmEditTime() {
    return this._confirmEditTime
  }

  @Mutation
  public setConfirmEditTime(time: number) {
    this._confirmEditTime = time
  }

  // 执行日志
  private _runLogs: any[] = []
  public get runLogs() {
    return this._runLogs
  }
  @Mutation
  public setRunLogs(logs: any[]) {
    this._runLogs = logs
  }

  //  刷新单个节点 更改 selectNode
  @Action({ commit: 'setSelectNode' })
  public async refreshTaskQueryById(id: number) {
    const response = await taskQueryById({ data: { id } })
    let node: any = null
    if (response.data.code === 100) {
      node = response.data.result
      // 更新pipeline
      const parameters = {
        id: node.projectId,
        pipelineId: node.pipelineId,
      }
      await this.queryPipelineNodes(parameters)
    }
    return node
  }

  // 当前节点添加清洗
  @Action({ commit: 'setSelectNode' })
  public async selectNodeAddCleanNode() {
    const { addCol, addRow } = ComputeSpaceAfterNode(this._pipelineNodes, {
      nodePosition: this._selectNode.data.position,
    })
    let node: any = null
    const parameters = {
      name: '清洗',
      projectId: this._selectNode.projectId,
      pipelineId: this._selectNode.pipelineId,
      parentId: this._selectNode.id,
      childId: null,
      type: 5, // 类型: 3--表示数据节点， 1--算子， 2--ETL算子
      data: {
        algName: '清洗',
        algType: 1,
        position: {
          row: addRow,
          col: addCol,
        },
      },
    }
    const response = await taskComplexLoad({ data: parameters })
    if (response.data.code === 100) {
      node = response.data.result
      const parameters2 = {
        id: node.projectId,
        pipelineId: node.pipelineId,
      }
      await this.queryPipelineNodes(parameters2)
    }
    return node
  }

  // StudioSideMenu collapsed 状态 (数据视图 & 可视化视图)
  private _collapsed: boolean = false
  @Mutation
  public setCollapsed(collapsed: boolean) {
    this._collapsed = collapsed
  }
  public get collapsed() {
    return this._collapsed
  }

  // StudioSideMenu 视图菜单是否显示
  @Mutation
  public setSideMenu(isShow: boolean) {
    this._isSideMenuShow = isShow
  }
  public get isSideMenuShow() {
    return this._isSideMenuShow
  }

  // Studio SidePanel 数据源算子面板是否显示
  @Mutation
  public setSidePanel(isShow: boolean) {
    this._isSidePanelShow = isShow
  }
  public get isSidePanelShow() {
    return this._isSidePanelShow
  }

  private _nodeEditPanelIsFullScreen: boolean = false
  @Mutation
  public setNodeEditPanelIsFullScreen(isFullScreen: boolean) {
    this._nodeEditPanelIsFullScreen = isFullScreen
  }
  public get nodeEditPanelIsFullScreen() {
    return this._nodeEditPanelIsFullScreen
  }

  // 节点编辑面板数据透视是否展开
  private _nodeEditPanelIsShowVisualization: boolean = false
  @Mutation
  public setNodeEditPanelIsShowVisualization(isShow: boolean) {
    this._nodeEditPanelIsShowVisualization = isShow
  }
  public get nodeEditPanelIsShowVisualization() {
    return this._nodeEditPanelIsShowVisualization
  }

  @Mutation
  public toggleSelectedColumn(column: any) {
    const index = this._selectedColumns.findIndex((c) => c === column)
    if (index !== -1) {
      this._selectedColumns.splice(index, 1)
    } else {
      this._selectedColumns.push(column)
    }
  }

  public get selectedColumns() {
    return this._selectedColumns
  }

  @Mutation
  public setSelectedColumns(selectedColumn: IColumn[]) {
    this._selectedColumns = selectedColumn
  }

  public get mergeColumnHotKey() {
    return this._mergeColumnHotKey
  }

  @Mutation
  public setMergeColumnHotKey(status: boolean) {
    this._mergeColumnHotKey = status
  }

  @Mutation
  public clearSelectedColumns() {
    if (this._selectedColumns.length > 0) {
      this._selectedColumns = []
    }
  }

  public get graphSize() {
    return this._graphSize
  }

  @Mutation
  public setGraphSize(size: any) {
    this._graphSize = size
  }

  // 执行完成时间
  public get executionCompletionTime() {
    return this._executionCompletionTime
  }

  @Mutation
  public setExecutionCompletionTime(time: number) {
    this._executionCompletionTime = time
  }

  public _executionCompletionType: boolean = false
  // 执行完成时间
  public get executionCompletionType() {
    return this._executionCompletionType
  }
  @Mutation
  public setExecutionCompletionType(type: boolean) {
    this._executionCompletionType = type
  }

  // 节点状态 map
  public get nodeStatusMap() {
    return this._nodeStatusMap
  }

  @Mutation
  public setNodeStatusMap(statusMap: NodeStatusMap) {
    this._nodeStatusMap = statusMap
  }

  public get savingWidgetConfig() {
    return this._savingWidgetConfig
  }

  @Mutation
  public setSavingWidgetConfig(widgetConfig: any) {
    this._savingWidgetConfig = widgetConfig
  }

  @Action({ commit: 'setSavingWidgetConfig' })
  public saveRecommendVisualization(widgetConfig: any) {
    return widgetConfig
  }
}

export default getModule(GraphViewStore)
